home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-06 / an201x.zip / TURCBTRV.C < prev    next >
Text File  |  1990-02-10  |  5KB  |  160 lines

  1. /*                                    */
  2. /*         Borland's Turbo C Version 2 interface to the               */
  3. /*        Btrieve Record Manager, version 4, 5, 5.1        */
  4. /*                                    */
  5.  
  6. #include <dos.h>
  7. #define BTR_ERR     20              /* record manager not started */
  8. #define BTR_INT     0x7B            /* Btrieve interrupt vector */
  9. #define BTR2_INT    0x2F         /* multi-user interrupt vector */
  10. #define BTR_VECTOR  BTR_INT * 4         /* offset for interrupt */
  11. #define BTR_OFFSET  0x33           /* Btrieve offset within segment */
  12. #define VARIABLE_ID 0x6176     /* id for variable length records - 'va' */
  13. #define _2FCODE     0xAB00     /* function code for int 2F to btrieve */
  14.  
  15.  
  16.  
  17. /*  For Compact, Large, and Huge memory models                 */
  18. /*  LMODEL means 32-bit pointers in use                  */
  19.  
  20. #if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__)
  21. #define LMODEL 1
  22. #endif
  23.  
  24.  
  25.  
  26. /* ProcId is used for communicating with the Multi Tasking Version of  */
  27. /* Btrieve. It contains the process id returned from BMulti and should */
  28. /* not be changed once it has been set.                    */
  29. /*                                       */
  30.  
  31. static unsigned ProcId = 0;        /* initialize to no process id */
  32. static char MULTI = 0;              /* flag set to true if MultiUser */
  33. static char VSet = 0;        /* flag set to true if checked version */
  34.  
  35. int BTRV (OP, POS_BLK, DATA_BUF, DATA_LEN, KEY_BUF, KEY_NUM)
  36.   int  OP;
  37.   char POS_BLK[];
  38.   char DATA_BUF[];
  39.   int  *DATA_LEN;
  40.   char KEY_BUF[];
  41.   int  KEY_NUM;
  42.  
  43. {
  44. union REGS b_regs;                    /* define registers */
  45.  
  46. struct SREGS b_sregs;                /* define segment registers */
  47.  
  48. struct BTRIEVE_PARMS      /* structure passed to Btrieve Record Manager */
  49.  {
  50.    char *BUF_OFFSET;              /* callers data buffer offset */
  51. #ifndef LMODEL
  52.    int     BUF_SEG;             /* callers data buffer segment */
  53. #endif
  54.    int     BUF_LEN;                   /* length of data buffer */
  55.    char *CUR_OFFSET;              /* user position block offset */
  56. #ifndef LMODEL
  57.    int     CUR_SEG;             /* user position block segment */
  58. #endif
  59.    char *FCB_OFFSET;                  /* offset of disk FCB */
  60. #ifndef LMODEL
  61.    int     FCB_SEG;                 /* segment of disk FCB */
  62. #endif
  63.    int     FUNCTION;                  /* requested function */
  64.    char *KEY_OFFSET;             /* offset of user's key buffer */
  65. #ifndef LMODEL
  66.    int     KEY_SEG;            /* segment of user's key buffer */
  67. #endif
  68.    char  KEY_LENGTH;             /* length of user's key buffer */
  69.    char  KEY_NUMBER;            /* key of reference for request */
  70.    int    *STAT_OFFSET;                   /* offset of status word */
  71. #ifndef LMODEL
  72.    int     STAT_SEG;                  /* segment of status word */
  73. #endif
  74.    int     XFACE_ID;                 /* language identifier */
  75.  } XDATA;
  76.  
  77. int STAT = 0;                      /* status of Btrieve call */
  78.  
  79. /*                                    */
  80. /*  Check to see that the Btrieve Record Manager has been started.    */
  81. /*                                    */
  82.  
  83. if (!VSet)             /* if we don't know version of Btrieve yet */
  84.  {
  85.   VSet = 1;
  86.   b_regs.x.ax = 0x3000;                /* check dos version */
  87.   int86x (0x21, &b_regs, &b_regs, &b_sregs);
  88.   if ((b_regs.x.ax & 0x00FF) >= 3)       /* if DOS version 3 or later */
  89.    {
  90.     b_regs.x.ax = _2FCODE;
  91.     int86x (BTR2_INT, &b_regs, &b_regs, &b_sregs);
  92.     MULTI = ((b_regs.x.ax & 0xFF) == 'M');/* if al is M, bmulti is loaded */
  93.    }
  94.  }
  95.  
  96. if (!MULTI)
  97.  {                        /* if bmulti not loaded */
  98.   b_regs.x.ax = 0x3500 + BTR_INT;
  99.   int86x (0x21, &b_regs, &b_regs, &b_sregs);
  100.   if (b_regs.x.bx != BTR_OFFSET)
  101.      return (BTR_ERR);
  102.  }
  103.  
  104. /*  Read segment registers and initialize segment part of addresses to    */
  105. /*  user's data segment.                                                */
  106. /*                                    */
  107.  
  108. segread (&b_sregs);
  109. #ifndef LMODEL
  110. XDATA.BUF_SEG = XDATA.CUR_SEG = XDATA.FCB_SEG =
  111.   XDATA.KEY_SEG = XDATA.STAT_SEG = b_sregs.ss;
  112. #endif
  113.  
  114. /*                                    */
  115. /*  Move user parameters to XDATA, the block where Btrieve expects them.*/
  116. /*                                    */
  117.  
  118. XDATA.FUNCTION      = OP;
  119. XDATA.STAT_OFFSET = &STAT;
  120. XDATA.FCB_OFFSET  = POS_BLK;
  121. XDATA.CUR_OFFSET  = POS_BLK + 38;
  122. XDATA.BUF_OFFSET  = DATA_BUF;
  123. XDATA.BUF_LEN      = *DATA_LEN;
  124. XDATA.KEY_OFFSET  = KEY_BUF;
  125. XDATA.KEY_LENGTH  = 255;         /* use max since we don't know */
  126. XDATA.KEY_NUMBER  = KEY_NUM;
  127. XDATA.XFACE_ID      = VARIABLE_ID;
  128.  
  129. /*                                    */
  130. /*  Make call to the Btrieve Record Manager.                */
  131. /*                                    */
  132.  
  133.  
  134. b_regs.x.dx = (int) &XDATA;  /* parameter block is expected to be in DX */
  135. b_sregs.ds = b_sregs.ss;
  136. if (!MULTI)
  137.   int86x (BTR_INT, &b_regs, &b_regs, &b_sregs);
  138. else
  139.  {                             /* call bmulti */
  140.   while (1)
  141.    {
  142.     b_regs.x.ax = 1;             /*  assume no proc id obtained yet */
  143.     if ((b_regs.x.bx = ProcId) != 0)        /* if we have a proc id */
  144.       b_regs.x.ax = 2;                    /* tell bmulti that */
  145.     b_regs.x.ax += _2FCODE;
  146.     int86x (BTR2_INT, &b_regs, &b_regs, &b_sregs);
  147.     if ((b_regs.x.ax & 0x00FF) == 0) break;    /* if call was processed */
  148.                            /* by bmulti, leave loop */
  149.     b_regs.x.ax = 0x0200;   /* if multilink advanced is loaded, it will */
  150.     int86x (0x7F, &b_regs, &b_regs, &b_sregs); /* it will switch processes */
  151.    }
  152.   if (ProcId == 0) ProcId = b_regs.x.bx;
  153.  }
  154.  
  155. *DATA_LEN = XDATA.BUF_LEN;
  156. return (STAT);                           /* return status */
  157. }
  158.  
  159.  
  160.